package cn.zhangfusheng.api.ui.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;

/**
 * @ClassName: HttpClientUtils
 * @Author: ZFS
 * @Date: 2018/10/12 13:26
 */
@Slf4j
@Component
public class HttpClientUtils {

    private static final String AGREEMENT_AFTER = "://";
    private static final String DOMAIN_AFTER = ":";
    private static final String PORT_AFTER = "/";
    private static final String GETPARAM_AFTER = "?";
    private static final String HOST = "HOST";


    /**
     * swagger 基础API访问
     *
     * @param agreement 协议
     * @param domain    域名
     * @param port      端口号
     * @param path      访问路径
     * @param method    请求方式
     * @param param     请求参数
     * @param request   请求
     * @param response  响应
     * @return string
     * @throws IOException IOException
     */
    public String requestUrl(String agreement, String domain, String port, String path, String method, String param,
                             HttpServletRequest request, HttpServletResponse response) throws IOException, URISyntaxException {
        // 设置Cookie
        CookieStore cookieStore = new BasicCookieStore();
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            log.info("设置cookie=====================");
            for (Cookie cookie : cookies) {
                BasicClientCookie basicClientCookie = new BasicClientCookie(cookie.getName(), cookie.getValue());
                basicClientCookie.setDomain(domain);
                basicClientCookie.setPath(StringUtils.isNotBlank(cookie.getPath()) ? cookie.getPath() : "/");
                log.info("cookie:{}", basicClientCookie);
                cookieStore.addCookie(basicClientCookie);
            }
        }
        // 生成客户端
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore) // 设置cookie
                .build();
        // 获取参数
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(agreement).append(AGREEMENT_AFTER).append(domain);
        // 80 443 端口处理
        if (!("80".equals(port) || "443".equals(port))) {
            urlBuilder.append(DOMAIN_AFTER).append(port);
        }
        // 路径前缀/处理
        if (path.indexOf(PORT_AFTER) == 0) {
            urlBuilder.append(path);
        } else {
            urlBuilder.append(PORT_AFTER).append(path);
        }
        // 请求参数处理
        if (StringUtils.isNotBlank(param)) {
            urlBuilder.append(GETPARAM_AFTER).append(param);
        }
        log.info("{}请求:url={}", method, urlBuilder.toString());
        // 获取请求方式
        final String[] requestMethod = new String[1];
        requestMethod[0] = method.toUpperCase();
        // 生成请求
        HttpRequestBase httpRequestBase = new HttpRequestBase() {
            @Override
            public String getMethod() {
                return requestMethod[0];
            }
        };
        httpRequestBase.setURI(URI.create(urlBuilder.toString()));
        // 设置 header
        // 设置Host的值
        urlBuilder.delete(0, urlBuilder.toString().length());
        urlBuilder.append(domain);
        if (!"80".equals(port)) {
            urlBuilder.append(DOMAIN_AFTER).append(port);
        }
        log.info("设置请求头header=================");
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            String headerValue = HOST.equals(headerName.toUpperCase()) ? urlBuilder.toString() : request.getHeader(headerName);
            log.info("header:{}={}", headerName, headerValue);
            httpRequestBase.setHeader(headerName, headerValue);
        }
        HttpResponse httpResponse = httpClient.execute(httpRequestBase);
        log.info("设置响应的header");
        Header[] allHeaders = httpResponse.getAllHeaders();
        if (allHeaders != null) {
            for (Header allHeader : allHeaders) {
                log.info("{}", allHeader);
                response.setHeader(allHeader.getName(), allHeader.getValue());
            }
        }
        String responseEntityStr = EntityUtils.toString(httpResponse.getEntity());
        ((CloseableHttpResponse) httpResponse).close();
        log.info("响应数据:{}", responseEntityStr);
        return responseEntityStr;
    }
}
